home *** CD-ROM | disk | FTP | other *** search
- /*
- * Title:
- * displaymap.c
- *
- * Authors:
- * Michael P. Schenck
- *
- * Purpose:
- * This module impliments an object hierarchy similar to the
- * one used in phigs. It allows subobjects and lists of nodes
- * which act as a series of command matricies.
- * A root node is always allocated first for an object. This
- * is followed by a list of other nodes whos matricies can
- * either be appended to the local matrix or can set a new
- * local matrix to thier own matrix. All of these nodes can
- * have models linked to them that will be transformed into
- * world coordinate (object parts) by using the concatenation
- * of the matrix from the previous level (if a subobject) and
- * and the current local matrix. A subobject is made by linking
- * another node to the subject link of a node in the previous
- * level. An action block (node) can be inserted after any
- * node already in the objects display map.
- * There is no current way to remove an individual action block,
- * only the removal of the entire object. If either of the
- * action block creation functions return NULL, then the nodes
- * could not be created. The values returned are pointers to
- * the blocks allowing access to the matrix, the model, and
- * its effect in the display map from a central point. For more
- * details on the way this hierarchy functions Refer to
- * Section 7.6 in Computer Graphics, Principles and Practice,
- * Foley, VanDam, ect.
- *
- * Copyright Info:
- * Copyright (C) 1993, 1994 -- by Michael P. Schenck,
- * (mps4466@ultb.isc.rit.edu)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a copy of the GNU General Public License
- * write to the Free Software Foundation, 675 Mass Ave,
- * Cambridge, MA 02139, USA.
- *
- */
-
- #include <stdlib.h>
- #include "/include/types.h"
- #include "/include/matrix.h"
- #include "/include/database.h"
- #include "/include/displaymap.h"
-
- static ULONG curnumobjects;
- static struct Action *roots[MAXROOTOBJECTS];
-
- extern struct Model *models[MAXNUMMODELS];
- extern struct Object *objects[MAXNUMOBJECTS];
-
- void traverseobject(struct Action *,MATRIX);
- void traverseactionblock(struct Action *,MATRIX,MATRIX);
- void evaluatemodel(ULONG,ULONG,MATRIX);
-
- /* Clears the entire display map. */
-
- void cleardisplaymap()
-
- {
- ULONG i;
-
- curnumobjects=0;
- for(i=0;i<MAXROOTOBJECTS;i++) {
- if(roots[i] != NULL)
- removeroot(roots[i]);
- roots[i]=NULL;
- }
- }
-
- /* Creates a root action for a new object. */
-
- struct Action *createrootaction(MATRIX transmatrix,ULONG model)
-
- {
- struct Action *new;
- ULONG i;
-
- if (((new=(struct Action *)malloc(sizeof(struct Action))) == NULL)&&(curnumobjects < MAXROOTOBJECTS))
- return(NULL);
- if((new->lm=allocatematrix())==NULL) {
- free((void *)new);
- return(NULL);
- }
- if((new->cmtm=allocatematrix())==NULL) {
- freematrix(new->lm);
- free((void *)new);
- return(NULL);
- }
- if(model!=NOMODEL) {
- if((new->object=allocateobject(model))==NOOBJECT) {
- freematrix(new->lm);
- freematrix(new->cmtm);
- free((void *)new);
- return(NULL);
- }
- }
- else
- new->object = NOOBJECT;
- new->transtype = SET;
- new->changed = TRUE;
- new->transmatrix = transmatrix;
- new->model = model;
- new->previous = NULL;
- new->next = NULL;
- new->subobject = NULL;
- i=0;
- while(roots[i]!=NULL)
- i++;
- roots[i]=new;
- curnumobjects++;
- return(new);
- }
-
- /* Inserts a new action block before the one specified in curaction.
- this block can be a subobject or an object on the same level. */
-
- struct Action *createaction(struct Action *curaction,MATRIX transmatrix,UBYTE transtype,ULONG model,UBYTE type)
-
- {
- struct Action *new;
-
- if((new=(struct Action *)malloc(sizeof(struct Action))) == NULL)
- return(NULL);
- if((new->lm=allocatematrix())==NULL) {
- free((void *)new);
- return(NULL);
- }
- if((new->cmtm=allocatematrix())==NULL) {
- freematrix(new->lm);
- free((void *)new);
- return(NULL);
- }
- if(model!=NOMODEL) {
- if((new->object=allocateobject(model))==NOOBJECT) {
- freematrix(new->lm);
- freematrix(new->cmtm);
- free((void *)new);
- return(NULL);
- }
- }
- else
- new->object = NOOBJECT;
- new->transtype = transtype;
- new->changed = TRUE;
- new->transmatrix = transmatrix;
- new->model = model;
- new->previous = curaction;
- if(type==CUROBJECT) {
- new->next = curaction->next;
- curaction->next = new;
- new->subobject = NULL;
- }
- else {
- new->subobject = curaction->subobject;
- curaction->subobject = new;
- new->next = NULL;
- }
- return(new);
- }
-
- /* Removes an entire object. */
-
- void removeroot(struct Action *root)
-
- {
- deallocateobject(root->object);
- freematrix(root->lm);
- freematrix(root->cmtm);
- if(root->subobject != NULL)
- removeaction(root->subobject);
- if(root->next != NULL)
- removeaction(root->next);
- free((void *)root);
- }
-
- /* Removes an action block and any action blocks below it. */
-
- void removeaction(struct Action *curaction)
-
- {
- deallocateobject(curaction->object);
- freematrix(curaction->lm);
- freematrix(curaction->cmtm);
- if(curaction->subobject != NULL)
- removeaction(curaction->subobject);
- if(curaction->next != NULL)
- removeaction(curaction->next);
- free((void *)curaction);
- }
-
- /* Begins traversal of the entire display tree. */
-
- void traversedisplaymap()
-
- {
- ULONG i;
- MATRIX gm;
-
- gm=allocatematrix();
- for(i=0;i<MAXROOTOBJECTS;i++) {
- if(roots[i] != NULL) {
- identitymatrix(gm);
- traverseobject(roots[i],gm);
- }
- }
- freematrix(gm);
- }
-
- /* Starts traversal of a new object or subobject. */
-
- void traverseobject(struct Action *cur,MATRIX gm)
-
- {
- if(cur->changed==TRUE) {
- if((cur->transmatrix!=NULL)&&((cur->transtype==SET)||(cur->transtype==APPEND)))
- copymatrix(cur->transmatrix,cur->lm);
- else
- identitymatrix(cur->lm);
- multmatrix(cur->lm,gm,cur->cmtm);
- if(cur->model!=NOMODEL)
- evaluatemodel(cur->model,cur->object,cur->cmtm);
- if(cur->next!=NULL)
- cur->next->changed=TRUE;
- if(cur->subobject!=NULL)
- cur->subobject->changed=TRUE;
- cur->changed=FALSE;
- }
- if(cur->subobject!=NULL)
- traverseobject(cur->subobject,cur->cmtm);
- if(cur->next!=NULL)
- traverseactionblock(cur->next,cur->lm,gm);
- }
-
- /* Traverses a single action block. */
-
- void traverseactionblock(struct Action *cur,MATRIX lm,MATRIX gm)
-
- {
- if(cur->changed==TRUE) {
- switch(cur->transtype) {
- case SET : copymatrix(cur->transmatrix,cur->lm);
- break;
- case APPEND : multmatrix(cur->transmatrix,lm,cur->lm);
- break;
- case NONE : identitymatrix(cur->lm);
- break;
- }
- multmatrix(cur->lm,gm,cur->cmtm);
- if(cur->model!=NOMODEL)
- evaluatemodel(cur->model,cur->object,cur->cmtm);
- if(cur->next!=NULL)
- cur->next->changed=TRUE;
- if(cur->subobject!=NULL)
- cur->subobject->changed=TRUE;
- cur->changed=FALSE;
- }
- if(cur->subobject!=NULL)
- traverseobject(cur->subobject,cur->cmtm);
- if(cur->next!=NULL)
- traverseactionblock(cur->next,cur->lm,gm);
- }
-
- /* Transform model verticies to object verticies (world coords). */
-
- void evaluatemodel(ULONG model,ULONG object,MATRIX transmatrix)
-
- {
- ULONG i;
-
- for(i=0;i<(models[model]->numvert*4);i+=4)
- multvecandmat(models[model]->verticies+i,transmatrix,objects[object]->verticies+i);
- }
-